home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 388_01 / ae / 93 / jul / command.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-17  |  8.2 KB  |  503 lines

  1. /*
  2.  * command.c        
  3.  *
  4.  * Anthony's Editor July 93
  5.  *
  6.  * Copyright 1993, 1993 by Anthony Howe.  All rights reserved.  No warranty.
  7.  */
  8.  
  9. #include <ctype.h>
  10. #include "header.h"
  11.  
  12. void prt_macros _((void));
  13. int yesno _((int));
  14. int more _((int));
  15. void prompt _((t_msg, char *, size_t));
  16.  
  17. void
  18. top()
  19. {
  20.     point = 0;
  21. }
  22.  
  23. void
  24. bottom()
  25. {
  26.     epage = point = pos(ebuf);
  27. }
  28.  
  29. void
  30. quit_ask()
  31. {
  32.     if (modified) {
  33.         standout();
  34.         mvaddstr(MSGLINE, 0, getmsg(p_notsaved));
  35.         standend();
  36.         clrtoeol();
  37.         if (!yesno(FALSE))
  38.             return;
  39.     }
  40.     quit();
  41. }
  42.  
  43. int
  44. yesno(flag)
  45. int flag;
  46. {
  47.     int ch;
  48.  
  49.     addstr(getmsg(flag ? p_yes : p_no));
  50.     refresh();
  51.     ch = getliteral();
  52.     if (ch == '\r' || ch == '\n')
  53.         return (flag);
  54.     return (ch == getmsg(p_yes)[1]);
  55. }
  56.  
  57. void
  58. quit()
  59. {
  60.     done = 1;
  61. }
  62.  
  63. void
  64. redraw()
  65. {
  66.     int col;
  67.  
  68.     clear();
  69.     if (textline != HELPLINE) {
  70.         move(HELPLINE, 0);
  71.         addstr(getmsg(m_help));
  72.         ruler(COLS);
  73.         getyx(stdscr, textline, col);
  74.     }
  75.     display(dispfull);
  76. }
  77.  
  78. void
  79. left()
  80. {
  81.     if (0 < point && iscrlf(--point) == 2)
  82.         --point;
  83.  
  84. void
  85. right()
  86. {
  87.     if (point < pos(ebuf) && iscrlf(point++) == 1)
  88.         ++point;
  89. }
  90.  
  91. void
  92. up()
  93. {
  94.     point = lncolumn(upup(point), col);
  95.     if (iscrlf(point) == 2)
  96.         --point;
  97. }
  98.  
  99. void
  100. down()
  101. {
  102.     point = lncolumn(dndn(point), col);
  103.     if (iscrlf(point) == 2)
  104.         --point;
  105. }
  106.  
  107. void
  108. lnbegin()
  109. {
  110.     point = segstart(lnstart(point), point);
  111. }
  112.  
  113. void
  114. lnend()
  115. {
  116.     point = dndn(point);
  117.     left();
  118. }
  119.  
  120. void
  121. wleft()
  122. {
  123.     while (!isalnum(*ptr(--point)) && 0 < point)
  124.         ;
  125.     while (isalnum(*ptr(--point)) && 0 <= point)
  126.         ;
  127.     ++point;
  128. }
  129.  
  130. void
  131. wright()
  132. {
  133.     t_point epoint = pos(ebuf);
  134.     while (isalnum(*ptr(point)) && point < epoint)
  135.         ++point;
  136.     while (!isalnum(*ptr(point)) && point < epoint) 
  137.         ++point;
  138. }
  139.  
  140. void
  141. pgdown()
  142. {
  143.     page = point = upup(epage);
  144.     while (textline < row--)
  145.         down();
  146.     epage = pos(ebuf);
  147. }
  148.  
  149. void
  150. pgup()
  151. {
  152.     int i = LINES;
  153.     while (textline < --i) {
  154.         page = upup(page);
  155.         up();
  156.     }
  157. }
  158.  
  159. void
  160. insert()
  161. {
  162.     assert(gap <= egap);
  163.     if (gap == egap && !growgap(CHUNK))
  164.         return;
  165.     point = movegap(point);
  166.     *gap++ = input == K_LITERAL ? getliteral() : input;
  167.     if (input == '\r' && (gap < egap || growgap(CHUNK)))
  168.         *gap++ = '\n';
  169.     modified = TRUE;
  170.     point = pos(egap);
  171. }
  172.  
  173. void
  174. insert_mode()
  175. {
  176.     int ch;
  177.     t_point opoint;
  178.     point = opoint = movegap(point);
  179.     undoset();
  180.     while ((ch = getkey(key_mode)) != K_INSERT_EXIT) {
  181.         if (ch == K_STTY_ERASE) {
  182.             if (opoint < point) {
  183.                 if (*--gap == '\n' 
  184.                 && buf < gap && gap[-1] == '\r')
  185.                     --gap;
  186.                 modified = TRUE;
  187.             }
  188.         } else {
  189.             assert(gap <= egap);
  190.             if (gap == egap && !growgap(CHUNK)) 
  191.                 break;
  192.             *gap++ = ch == K_LITERAL ? getliteral() : ch;
  193.             if (ch == '\r' && (gap < egap || growgap(CHUNK)))
  194.                 *gap++ = '\n';
  195.             modified = TRUE;
  196.         }
  197.         point = pos(egap);
  198.         display(dispfull);
  199.     }
  200. }
  201.  
  202. void
  203. backsp()
  204. {
  205.     point = movegap(point);
  206.     undoset();
  207.     if (buf < gap) {
  208.         if (*--gap == '\n' && buf < gap && gap[-1] == '\r')
  209.             --gap;
  210.         point = pos(egap);
  211.         modified = TRUE;
  212.     }
  213. }
  214.  
  215. void
  216. delete()
  217. {
  218.     point = movegap(point);
  219.     undoset();
  220.     if (egap < ebuf) {
  221.         if (*egap++ == '\r' && egap < ebuf && *egap == '\n')
  222.             ++egap;
  223.         point = pos(egap);
  224.         modified = TRUE;
  225.     }
  226. }
  227.  
  228. void
  229. readfile()
  230. {
  231.     temp[0] = '\0';
  232.     prompt(p_read, temp, BUFSIZ);
  233.     (void) load(temp);
  234.     if (filename[0] == '\0') {
  235.         strcpy(filename, temp);
  236.         modified = FALSE;
  237.     }
  238. }
  239.  
  240. void
  241. writefile()
  242. {
  243.     standout();
  244.     if (marker == NOMARK || point == marker) {
  245.         strcpy(temp, filename);
  246.         prompt(p_write, temp, BUFSIZ);
  247.     } else {
  248.         temp[0] = '\0';
  249.         prompt(p_bwrite, temp, BUFSIZ);
  250.     }
  251.     (void) save(temp);
  252.     if (marker == NOMARK && filename[0] == '\0') 
  253.         strcpy(filename, temp);
  254. }
  255.  
  256. void
  257. help()
  258. {
  259.     textline = textline == HELPLINE ? -1 : HELPLINE;
  260.     /* When textline != HELPLINE, then redraw() will compute the 
  261.      * actual textline that follows the help text.
  262.      */
  263.     redraw();
  264. }
  265.  
  266. void
  267. block()
  268. {
  269.     marker = marker == NOMARK ? point : NOMARK;
  270. }
  271.  
  272. void
  273. cut()
  274. {
  275.     if (marker == NOMARK || point == marker)
  276.         return;
  277.     if (scrap != NULL) {
  278.         free(scrap);
  279.         scrap = NULL;
  280.     }
  281.     if (point < marker) {
  282.         (void) movegap(point);
  283.         nscrap = marker - point;
  284.     } else {
  285.         (void) movegap(marker);
  286.         nscrap = point - marker;
  287.     }
  288.     if ((scrap = (t_char*) malloc(nscrap)) == NULL) {
  289.         msg(m_alloc);
  290.     } else {
  291.         undoset();
  292.         (void) memcpy(scrap, egap, nscrap * sizeof (t_char));
  293.         egap += nscrap;
  294.         block();
  295.         point = pos(egap);
  296.         modified = TRUE;
  297.     }
  298. }
  299.  
  300. void
  301. paste()
  302. {
  303.     if (nscrap <= 0) {
  304.         msg(m_scrap);
  305.     } else if (nscrap < egap-gap || growgap(nscrap)) {
  306.         point = movegap(point);
  307.         undoset();
  308.         memcpy(gap, scrap, nscrap * sizeof (t_char));
  309.         gap += nscrap;
  310.         point = pos(egap);
  311.         modified = TRUE;
  312.     }
  313. }
  314.  
  315. void
  316. version()
  317. {
  318.     msg(m_version);
  319. }
  320.  
  321. void
  322. macro()
  323. {
  324.     t_keymap *kp;
  325.     size_t buflen, rhsoff;
  326.     char *buf, *lhs, *rhs;
  327.  
  328.     if ((buf = (char *) malloc(BUFSIZ)) == NULL) {
  329.         msg(m_alloc);
  330.         return;
  331.     }
  332.     buf[0] = '\0';
  333.     prompt(p_macro, buf, BUFSIZ);
  334.     buflen = strlen(buf)+1;
  335.  
  336.     if ((lhs = strtok(buf, " \t")) == NULL) {
  337.         prt_macros();
  338.     } else if (buf < lhs) {
  339.         /* Ideally we should shuffle the buffer down so that
  340.          * the lhs starts at the beginning of buffer.
  341.          */
  342.         msg(m_error);
  343.     } else if (encode(lhs) < 0) {
  344.         msg(m_badescape);
  345.     } else {
  346.         kp = findkey(key_map, lhs);
  347.         if ((rhs = strtok(NULL, " \t")) == NULL) {
  348.             /* Delete macro. */
  349.             if (kp == NULL || kp->code != K_MACRO_DEFINE) {
  350.                 msg(m_nomacro);
  351.             } else {
  352.                 free(kp->lhs);
  353.                 kp->lhs = kp->rhs = NULL;
  354.             }
  355.         } else if (encode(rhs) < 0) { 
  356.             msg(m_badescape);
  357.         } else {
  358.             rhsoff = (size_t)(rhs - buf);
  359.             if ((buf = (char *) realloc(buf, buflen)) == NULL) {
  360.                 free(buf);
  361.                 msg(m_alloc);
  362.                 return;
  363.             }
  364.  
  365.             if (kp == NULL) {
  366.                 /* Find free slot to add macro. */
  367.                 for (kp = key_map; kp->code != K_ERROR; ++kp) {
  368.                     if (kp->code == K_MACRO_DEFINE
  369.                     && kp->lhs == NULL)
  370.                         break;
  371.                 }
  372.             }
  373.             if (kp->code == K_ERROR) {
  374.                 msg(m_slots);
  375.             } else if (kp->code == K_MACRO_DEFINE) {
  376.                 /* Change macro. */
  377.                 kp->lhs = buf;
  378.                 kp->rhs = buf + rhsoff;
  379.                 return;
  380.             } else {
  381.                 msg(m_nomacro);
  382.             }
  383.         }
  384.     }
  385.     free(buf);
  386. }
  387.  
  388. void
  389. prt_macros()
  390. {
  391.     t_keymap *kp;
  392.     int used, total;
  393.     unsigned char *ptr;
  394.  
  395.     erase();
  396.     scrollok(stdscr, TRUE);
  397.     for (used = total = 0, kp = key_map; kp->code != K_ERROR; ++kp) {
  398.         if (kp->code == K_MACRO_DEFINE) {
  399.             ++total;
  400.             if (kp->rhs != NULL) {
  401.                 ++used;
  402.                 addch('{');
  403.                 ptr = (unsigned char *) kp->lhs; 
  404.                 for (; *ptr != '\0'; ++ptr) 
  405.                     addstr(printable(*ptr));
  406.                 addstr("}\t{");
  407.                 ptr = (unsigned char *) kp->rhs; 
  408.                 for (; *ptr != '\0'; ++ptr) 
  409.                     addstr(printable(*ptr));
  410.                 addstr("}\n");
  411.                 (void) more(used);
  412.             }
  413.         }
  414.     }
  415.     printw("\n%d/%d\n", used, total);
  416.     scrollok(stdscr, FALSE);
  417.     (void) more(-1);
  418.     redraw();
  419. }
  420.  
  421. /*
  422.  * Return true if more should continue.
  423.  */
  424. int
  425. more(row)
  426. int row;
  427. {
  428.     int ch;
  429.  
  430.     if (0 < row % (LINES-1))
  431.         return (TRUE);
  432.     standout();
  433.     addstr(getmsg(p_more));
  434.     standend();
  435.     clrtoeol();
  436.     refresh();
  437.     ch = getliteral();
  438.     addch('\r');
  439.     clrtoeol();
  440.     return (ch != getmsg(p_quit)[1] && ch != getmsg(p_no)[1]);
  441. }
  442.  
  443. /*
  444.  * Flip the case of a region.  
  445.  */
  446. void
  447. flipcase()
  448. {
  449.     t_char *p;
  450.     t_region r;
  451.     for (getregion(&r); r.left <= r.right; ++r.left) {
  452.         p = ptr(r.left);
  453.         if (islower(*p)) {
  454.             *p = toupper(*p);
  455.             modified = TRUE;
  456.         } else if (isupper(*p)) {
  457.             *p = tolower(*p);
  458.             modified = TRUE;
  459.         }
  460.     }
  461.     if (marker == NOMARK)
  462.         right();
  463. }
  464.  
  465. void
  466. prompt(m, buf, len)
  467. t_msg m;
  468. char *buf;
  469. size_t len;
  470. {
  471.     standout();
  472.     mvaddstr(MSGLINE, 0, getmsg(m));
  473.     standend();
  474.     clrtoeol();
  475.     addch(' ');
  476.     refresh();
  477.     getinput(buf, len, TRUE);
  478. }
  479.  
  480. /*
  481.  * Return 1 if offset points to first-half of CR-LF; 
  482.  * 2 if offset points to second-half of CR-LF; 0 otherwise.
  483.  */
  484. int
  485. iscrlf(offset)
  486. register t_point offset;
  487. {
  488.     register t_char *p;
  489.  
  490.     p = ptr(offset);
  491.     if (*p == '\r') {
  492.         /* Look to the right for '\n'. */
  493.         if (++offset < pos(ebuf) && *ptr(offset) == '\n')
  494.             return (1);
  495.     } else if (*p == '\n') {
  496.         /* Look to the left for '\r'. */
  497.         if (pos(buf) < offset && *ptr(--offset) == '\r')
  498.             return (2);
  499.     }
  500.     return (0);
  501. }
  502.